﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Company.Database;
using Company.Database.Sqlite;
using Company.Plc;
using Company.Shell.Interfaces;
using Company.Shell.Models;
using LiveCharts.Defaults;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace Company.Shell.Services
{
    class RoomManager : ObservableObject, IRoomManager
    {
        public ICommand? SelectProgramCommand { get; }
        public ICommand? RunCommand { get; }
        public ICommand? StopCommand { get; }
        private IPlc Plc { get; }
        private IConfigProvider ConfigProvider { get; }
        private ICacheManager CacheManager { get; }
        private IProgramManager ProgramManager { get; }
        private IAlarmRepository AlarmRepository { get; }
        public RoomManager(
            IAlarmRepository alarmRepository,
            IProgramManager  programManager,
            ICacheManager cacheManager, 
            IConfigProvider configProvider,
            IPlc plc)
        {
            AlarmRepository = alarmRepository;
            ProgramManager = programManager;
            CacheManager = cacheManager;
            ConfigProvider = configProvider;
            Plc = plc;
            SelectProgramCommand = new RelayCommand<ProgramEntity>(OnSelectProgramCommand);
            RunCommand = new AsyncRelayCommand(OnRunCommand);
            StopCommand = new AsyncRelayCommand(OnStopCommand);
        }
        /// <summary>
        /// 结束运行当前房间
        /// </summary>
        private async Task OnStopCommand()
        {
            if (Room != null)
            {
                await Room.StopAsync();
            }
        }
        /// <summary>
        /// 开始运行当前房间
        /// </summary>
        private async Task OnRunCommand()
        {
            if (Room != null)
            {
                await Room.RunAsync();
            }
        }

        //为当前房间选定要运行的程序
        private void OnSelectProgramCommand(ProgramEntity? program)
        {
            if (Room != null && program != null)
            {
                Room.Program= program;

                //计算时间
                var temperatures = Room.Program.Temperatures as IList<ObservablePoint>;
                var humidities = Room.Program.Humidities as IList<ObservablePoint>;
                ObservablePoint? temperature = temperatures.LastOrDefault();
                ObservablePoint? humidity = humidities.LastOrDefault();
                if(temperature != null && humidity != null)
                {
                    var minute = temperature.X > humidity.X ? temperature.X : humidity.X;
                    var timespan = TimeSpan.FromMinutes(minute);
                    Room.TotalTime = timespan;
                }
            }
        }

        private ObservableCollection<RoomEntity> rooms = new();
        public ObservableCollection<RoomEntity> Rooms
        {
            get { return rooms; }
            set { SetProperty(ref rooms, value); }
        }
        private RoomEntity? room;
        public RoomEntity? Room
        {
            get { return room; }
            set { SetProperty(ref room, value); }
        }

        private readonly object _lock = new object();
        /// <summary>
        /// 房间初始化
        /// </summary>
        /// <returns></returns>
        public async Task Initialize()
        {
            ObservableCollection<RoomEntity> collection = new();
            await Task.Delay(500);
            await Task.Run(() =>
            {
                int count = ConfigProvider.Config.SoftwareConfig.RoomCount;
                ushort startAddress = 1000;
                for (int i = 0; i < count; i++)
                {
                    //生成房间
                    RoomEntity room = new RoomEntity(Plc, ConfigProvider);
                    room.Id = i + 1;
                    room.Name = $"房间{room.Id}";
                    room.Address = startAddress;
                    collection.Add(room);
                    startAddress = (ushort)(startAddress + 100);//每个房间占100个寄存器

                    //加载房间参数
                    var param = ConfigProvider.Config.SoftwareConfig.RoomParameters.FirstOrDefault(t => t.RoomId == room.Id);
                    if (param == null)
                    {
                        param = new RoomParameter { RoomId = room.Id };
                        ConfigProvider.Config.SoftwareConfig.RoomParameters.Add(param);
                    }
                    room.RoomParameter = param;

                    //加载房间缓存
                    var cache = CacheManager.Caches.FirstOrDefault(t => t.RoomId == room.Id);
                    if(cache == null)
                    {
                        cache = new CacheEntity() { RoomId = room.Id };
                        CacheManager.Caches.Add(cache);
                        CacheManager.Save();
                    }
                    room.Cache = cache;

                    //使用缓存数据
                    var program = ProgramManager.Programs.FirstOrDefault(t => t.Name == room.Cache.ProgramName);
                    if(program != null)
                    {
                        room.Program = program;
                        if(room.Cache.RoomMode== Enums.RoomMode.Running)
                        {
                            //接续上次运行
                            room.RunAsync(room.Cache.StartTime);
                        }
                    }

                    //保存报警记录
                    room.OnAlarm += (entity) =>
                    {
                        lock (_lock)
                        {
                            AlarmRepository.Insert(entity);
                        }
                    };
                }

                //显示房间
                foreach (RoomEntity room in collection)
                {
                    Room ??= room;
                    Rooms.Add(room);
                }
            });
        }
    }
}
